package com.wanbatv.wanba.jianshencao.api;

import android.text.TextUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by Forcs on 15/7/1.
 *
 * 网络API接口构造器
 */
public class ApiBuilder {

    private String mScheme;
    private String mIp = null;
    private int mPort = 80;
    private String mPath = null;
    private HashMap<String, ParamValue> mParams = new HashMap<>();

    /**
     * 根据渠道号初始化，协议头采用默认的HTTP
     * @param channelId 渠道号
     */
    public ApiBuilder(int channelId) {
        ApiHostFactory factory = ApiHostFactory.getInstance();
        ApiHost host = factory.getApiHost(channelId);
        mIp = host.ip;
        mPort = host.port;
    }

    /**
     * 用ip初始化，端口默认使用80
     * @param ip IP地址
     */
    public ApiBuilder(String ip) {
        this(ip, 80);
    }

    /**
     * 用ip和端口初始化
     * @param ip IP地址
     * @param port 端口号
     */
    public ApiBuilder(String ip, int port) {
        mIp = ip;
        mPort = port;
    }

    /**
     * 设置协议头，http | https | ftp
     * @param scheme 协议头
     * @return
     */
    public ApiBuilder scheme(String scheme) {
        mScheme = scheme;
        return this;
    }

    /**
     * 设置端口号
     * @param port 端口号
     * @return this
     */
    public ApiBuilder atPort(int port) {
        mPort = port;
        return this;
    }

    /**
     * 加入API路径
     * @param path 路径
     * @return this
     */
    public ApiBuilder withApi(String path) {
        mPath = path;
        return this;
    }

    /**
     * 加入整型参数
     * @param name 参数名
     * @param value 参数值
     * @return this
     */
    public ApiBuilder addParam(String name, String value) {
        mParams.put(name, new StringParamValue(value));
        return this;
    }

    /**
     * 加入字符参数
     * @param name 参数名
     * @param value 参数值
     * @return this
     */
    public ApiBuilder addParam(String name, int value) {
        mParams.put(name, new IntParamValue(value));
        return this;
    }

    /**
     * 加入浮点型参数
     * @param name 参数名
     * @param value 参数值
     * @return this
     */
    public ApiBuilder addParam(String name, float value) {
        mParams.put(name, new FloatParamValue(value));
        return this;
    }

    /**
     * 加入浮点型参数
     * @param name 参数名
     * @param value 参数值
     * @return this
     */
    public ApiBuilder addParam(String name, double value) {
        mParams.put(name, new DoubleParamValue(value));
        return this;
    }

    /**
     * 加入日期参数
     * @param name 参数名
     * @param value 参数值
     * @return this
     */
    public ApiBuilder addParam(String name, Date value) {
        mParams.put(name, new DateParamValue(value));
        return this;
    }

    /**
     * 创建API地址
     * [schema]://[host]/[path]?[参数名]=[参数值]&[参数名]=[参数值].....
     * @return API地址
     */
    public String create() {
        if (!TextUtils.isEmpty(mScheme)) {
            if (!ApiScheme.HTTP.equals(mScheme) && !ApiScheme.HTTPS.equals(mScheme)) {
                throw new IllegalArgumentException("Scheme " + mScheme + " is invalid");
            }
        } else {
            mScheme = ApiScheme.HTTP;
        }
        StringBuilder res = new StringBuilder(mScheme).append("://")
                .append(mIp).append(":").append(mPort).append("/")
                .append(mPath);
        if (!mParams.isEmpty()) {
            StringBuilder params = new StringBuilder("?");
            Iterator<Map.Entry<String, ParamValue>> it = mParams.entrySet().iterator();
            while (true) {
                Map.Entry<String, ParamValue> entry = it.next();
                params.append(entry.getKey()).append("=").append(entry.getValue().value());
                if (it.hasNext()) {
                    params.append("&");
                } else {
                    break;
                }
            }
            res.append(params);
        }

        return res.toString();
    }

    private interface ParamValue {
        String value();
    }

    private static class IntParamValue implements ParamValue {

        private int mValue;

        IntParamValue(int v) {
            mValue = v;
        }

        @Override
        public String value() {
            return "" + mValue;
        }
    }

    private static class StringParamValue implements ParamValue {

        private String mValue;

        StringParamValue(String v) {
            mValue = v;
        }

        @Override
        public String value() {
            String v = mValue;
            try {
                v = URLEncoder.encode(v, "utf-8");
            } catch (UnsupportedEncodingException e) {
            }
            return v;
        }
    }

    private static class FloatParamValue implements ParamValue {

        private float mValue;

        FloatParamValue(float v) {
            mValue = v;
        }

        @Override
        public String value() {
            return "" + mValue;
        }
    }

    private static class DoubleParamValue implements ParamValue {

        private double mValue;

        DoubleParamValue(double v) {
            mValue = v;
        }

        @Override
        public String value() {
            return "" + mValue;
        }
    }

    private static class DateParamValue implements ParamValue {

        private Date mValue;

        DateParamValue(Date v) {
            mValue = v;
        }

        @Override
        public String value() {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            return df.format(mValue);
        }
    }

}
